
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "consola.h"
#include "FuncionesPPD.h"
#include "Socket-Server.h"
#include "Prueba-ArchConfig.h"
#include "serializable.h"


const char * _EXIT = "exit";
const char * _INFO = "info";
const char * _CLEAR = "clear";
const char * _TRACE = "trace";



void Command_info(){

	printf("Posicion Actual %i:%i\n",CHSActual->Cilindro,CHSActual->Sector);

}


void Command_clear(char * sectores, int32_t sock){
	tInfo *InfoNodo;
	char sectorInicial[30 + 1];
	char sectorFinal[30 + 1];

	memset(sectorInicial, 0, 31);
	memset(sectorFinal, 0, 31);
	strncpy(sectorInicial, sectores, strpos(sectores, ' '));
	sectorInicial[30] = '\0';
	strncpy(sectorFinal, &sectores[strpos(sectores, ' ') + 1], strlen(sectores)-1);
	sectorFinal[30]= '\0';
	int32_t inicio;
	unsigned char* clear;
	clear= (unsigned char*)malloc(512);
	memset(clear ,0 , sizeof(clear));
	for(inicio=atoi(sectorInicial) ; inicio <= atoi(sectorFinal) ;++inicio ){
		InfoNodo = (tInfo*)malloc(sizeof(tInfo));
		InfoNodo->type = msgWrite;
		InfoNodo->sector = inicio;
		InfoNodo->socket = -1; //para que el planificador no cierre el sock
		InfoNodo->dato = clear;
		InfoNodo->Sig = NULL;
		AgregarLista(InfoNodo);

	}
}


void Command_trace(char * sectores, int32_t sock){
	tInfo *InfoNodo;
	int32_t cantidad;
	int32_t n= 0;
	int32_t nroSector[30];
	char * saveptr;
	char * auxSector;
	char * inputSectors;

	n = 0;
	inputSectors = calloc(strlen(sectores) + 1, sizeof(char));
	strcpy(inputSectors, sectores);
	auxSector = strtok_r(inputSectors, " ", &saveptr);
	while(auxSector != NULL) {
		nroSector[n] = atoi(auxSector);
		auxSector = strtok_r(NULL, " ", &saveptr);
		n++;
	}
	free(inputSectors);

	for(cantidad=0 ; cantidad < n ;++cantidad ){
		InfoNodo = (tInfo*)malloc(sizeof(tInfo));
		InfoNodo->type = 3;
		InfoNodo->sector = nroSector[cantidad];//sector[cantidad];
		InfoNodo->socket = sock;
		InfoNodo->dato = 0;
		InfoNodo->Sig = NULL;
		AgregarLista(InfoNodo);
		//sincreonizar tracert
		pthread_mutex_lock(&sem_Tracer);
		Tracer= Tracer + 1;
		pthread_mutex_unlock(&sem_Tracer);
	}
	while(Tracer!=0);

}



void Command_execute(char * command, char * sectores,int32_t Sock)
{
	if(strcmp(command, _INFO) == 0) {
		Command_info();
		return;
	}
	if(strcmp(command, _CLEAR) == 0) {
		Command_clear(sectores,Sock);
		return;
	}
	if(strcmp(command, _TRACE) == 0) {
		Command_trace(sectores,Sock);
		return;
	}
	if(strcmp(command, _EXIT) == 0) {
		exit(1);
		return;
	}

}

int ConsolePPD_Run(char *line, int32_t Sock)
{
	char command[30 + 1];
	char sectores[256 + 1];
	memset(command, 0, 31);
	memset(sectores, 0, 257);
	if (strpos(line, ' ') > 0) {
			strncpy(command, line, strpos(line, ' '));
			command[30] = '\0';
			strncpy(sectores, &line[strpos(line, ' ') + 1], strpos(line, '\n') - 1 - strpos(line, ' '));
			//sectores[256] = '\0';
		}
	else {
			strncpy(command, line, strpos(line, '\n'));
			command[30] = '\0';
		}
	Command_execute(command, sectores,Sock);
	return 0;
}


void *TconsolaServer ( void *parametro){
	datosConfigPPD * config=(datosConfigPPD *) parametro;
	char Cadena1[600];
	char comando[600];
	int32_t sock1;
	struct sockaddr_un direccionRem;
	socklen_t direccionRemSize;

	sock1 =CreaConexionServer_UNIX((char *)config->puertoConsola);

	if(sock1 != -1){
		direccionRemSize =strlen((char *)config->puertoConsola);
		int32_t NewSock = accept(sock1,(struct sockaddr *) &direccionRem, &direccionRemSize);
//		printf("Accept ok\n");
		recv(NewSock,Cadena1, 512,MSG_CONFIRM);
		strncpy(comando, Cadena1, strpos(Cadena1, '\n') +1 );

		while(strcmp(comando, "exit") != 0){
//			printf("lo que llego: %s \n",comando);
			ConsolePPD_Run(comando, NewSock);
			//----------------------------//
			strcpy (Cadena1, "ok");
			send(NewSock,Cadena1,strlen("ok"),MSG_CONFIRM);
			memset(Cadena1,0,strlen(Cadena1));
			memset(comando,0,strlen(comando));
			recv(NewSock,Cadena1, 512,MSG_CONFIRM);
			strncpy(comando, Cadena1, strpos(Cadena1, '\n') +1);
		}
		strcpy (Cadena1, "exit");
		send(NewSock,Cadena1,strlen("exit"),MSG_CONFIRM);
		close(NewSock);
	}
	close(sock1);
	return NULL;
}
